﻿/*
* WatchMyToon Plugin for HB
*     Codebase
*       2012
*  
* */
///////////////////////////////////////////
//			Things to Work On
//
//
//	~~~~~~~~~Section DoWork~~~~~~~~~
//	5) Clean Up Bags/Class/Spec/Position Code
//	7) Correctly Handle Character Selection Screen / Loading Screens
//
//	~~~~~~~~~Section Updates~~~~~~~~~
//	*) Settings Panel (Full Feature)
//	*) Guild/Party Roster
//	*) Screen Shots (Using DB not FTP)
//	*) Bot Stop / Start ... ? What about relogers (ie. HBRelog and ARelog)
//	*) Prowel Notificcoders cation.... ? Maybe
//
///////////////////////////////////////////
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Globalization;
using System.Drawing;
using System.Data.Odbc;
using System.Text.RegularExpressions;
using System.Windows.Forms;
using System.Web;
using System.Net;
using System.Windows.Media;
//!CompilerOption:AddRef:Newtonsoft.Json.dll
using Newtonsoft.Json.Linq;

using Styx;
using Styx.Common;
using Styx.CommonBot;
using Styx.Plugins;
using Styx.WoWInternals;


namespace WatchMyToon
{
    public class WatchMyToon : HBPlugin
    {
        //Plugin Details
        public ScreenCapture scr = new ScreenCapture();
        public override string Name { get { return "WatchMyToon"; } }
        public override string Author { get { return "Codebase & CoDeRs"; } }
        public override Version Version { get { return new Version(2, 0, 0); } }
        public const string dbVersion = "V2.0.0";

        //Plugin Status
        public static bool IsInitialized = false;
        public static bool doWork = true;
        public bool CharInfoUpdated = false;
        public bool stop = false;
        public Thread workerThread;
        public static string sCommandCheck = string.Empty;
        //Database Information
        public DateTime last_update;

        //Character Information
        public static int nToonId;
        public string Realm = string.Empty;
        public string Server = string.Empty;
        public string Side = string.Empty;
        public string nToonDetails = string.Empty;
        public string nToonIdString = string.Empty;
        public static string[] arrTokens = new string[20] { "61", "81", "241", "361", "384", "385", "390", "391", "392", "393", "394", "395", "396", "397", "398", "399", "400", "401", "402", "515" };
        public static string[] Gender = new string[3] { "Unknown", "Male", "Female" };
        public static bool bIsLootClosed = true;
        public static bool bIsInLoadingScreen = false;

        //Debug Information
        public string updateSection = string.Empty;

        // Declaring SubClasses
        public Functions_Chat ChatFunctions = new Functions_Chat();
        public Lua_Events LuaEvents = new Lua_Events();
        public SVNUpdater PluginUpdater = new SVNUpdater();
        public Fucntions_Unit UnitFunctions = new Fucntions_Unit();
        public SQL_Connector SQLConnector = new SQL_Connector();

        // Use this to init the Plugin
        public override void Initialize()
        {
            if (IsInitialized) return;
            try
            {
                //Checking for Plugin Updates in SVN
                Logging.Write(LogLevel.Normal, Colors.Green, "[WatchMyToon] - Checking for Updates");
                //PluginUpdater.CheckForUpdate(Version);

                //Adding Events
                Logging.Write(LogLevel.Normal, Colors.Green, "[WatchMyToon] - Loading All Events");
                //Chat Events Here
                Styx.CommonBot.Chat.Whisper += ChatFunctions.WoWChat_Whisper;
                Styx.CommonBot.Chat.Guild += ChatFunctions.WoWChat_Guild;
                Styx.CommonBot.Chat.Say += ChatFunctions.WoWChat_Say;
                Styx.CommonBot.Chat.Yell += ChatFunctions.WoWChat_Yell;
                Styx.CommonBot.Chat.Battleground += ChatFunctions.WoWChat_Battleground;
                Styx.CommonBot.Chat.Party += ChatFunctions.WoWChat_Party;
                Styx.CommonBot.Chat.Raid += ChatFunctions.WoWChat_Raid;

                //Loot Events Here
                Lua.Events.AttachEvent("CHAT_MSG_LOOT", LuaEvents.Loot); 						//Unit Receives Loot - Completed 08/08/2012 ~ CoDeRs
                Lua.Events.AttachEvent("CHAT_MSG_MONEY", LuaEvents.Loot);	    				//Unit Receives Gold Loot - Completed 08/08/2012 ~ CoDeRs
                Lua.Events.AttachEvent("LOOT_CLOSED", LuaEvents.LootClosed);
                Lua.Events.AttachEvent("BAG_UPDATE", LuaEvents.BagUpdate);

                //Money/Gold Change Events
                Lua.Events.AttachEvent("PLAYER_MONEY", LuaEvents.PLAYER_MONEY);

                //Achievement Events Here
                Lua.Events.AttachEvent("ACHIEVEMENT_EARNED", LuaEvents.ACHIEVEMENT_EARNED);		//Unit Completes Achievement (ID ONLY) - Completed 08/08/2012 ~ CoDeRs

                //Quest Events Here
                Lua.Events.AttachEvent("QUEST_ACCEPTED", LuaEvents.QUEST_ACCEPTED);				//Unit Accepts Quest from Quest Giver - Completed 08/08/2012 ~ CoDeRs
                Lua.Events.AttachEvent("QUEST_WATCH_UPDATE", LuaEvents.QUEST_WATCH_UPDATE);		//Unit's Quest has Updates (Kill, Item Looted, Completed(Flag Issued)) - Completed 08/08/2012 ~ CoDeRs

                //Player Events Here
                Lua.Events.AttachEvent("PLAYER_ENTERING_WORLD", LuaEvents.PLAYER_ENTERING_WORLD);
                Lua.Events.AttachEvent("PLAYER_LEVEL_UP", LuaEvents.PLAYER_LEVEL_UP);
                Lua.Events.AttachEvent("PLAYER_GUILD_UPDATE", LuaEvents.GUILD_INVITE_CANCEL);
                Lua.Events.AttachEvent("PLAYER_XP_UPDATE", LuaEvents.PLAYER_XP_UPDATE);
                Lua.Events.AttachEvent("UNIT_POWER", LuaEvents.UNIT_POWER);
                Lua.Events.AttachEvent("UNIT_HEALTH", LuaEvents.UNIT_HEALTH);
                
                //Zone Changeing Events Here
                Lua.Events.AttachEvent("ZONE_CHANGED", LuaEvents.ZONE_CHANGED);
                Lua.Events.AttachEvent("ZONE_CHANGED_NEW_AREA", LuaEvents.ZONE_CHANGED_NEW_AREA);

                //Reputation Events Here
                Lua.Events.AttachEvent("UPDATE_FACTION", LuaEvents.UPDATE_FACTION);				//Unit Reputation Update/Change

                //Guild Events Here
                Lua.Events.AttachEvent("GUILD_INVITE_REQUEST", LuaEvents.GUILD_INVITE_REQUEST); //Unit was Invited to a Guild (Inviter Name, Guild Name) - Completed 08/08/2012 ~ CoDeRs
                Lua.Events.AttachEvent("GUILD_INVITE_CANCEL", LuaEvents.GUILD_INVITE_CANCEL); 	//Unit Declines Invite to a Guild - Completed 08/08/2012 ~ CoDeRs                 
                Lua.Events.AttachEvent("GUILD_XP_UPDATE", LuaEvents.GUILD_XP_UPDATE);           //Event Triggers on Guild Update

                //Party Events Here
                Lua.Events.AttachEvent("PARTY_INVITE_REQUEST", LuaEvents.PARTY_INVITE_REQUEST); //Unit was Invited to a Guild (Party Leader Name) - Completed 08/08/2012 ~ CoDeRs
                Lua.Events.AttachEvent("PARTY_INVITE_CANCEL", LuaEvents.PARTY_INVITE_CANCEL);	//Unit Declines Invite to Party - Completed 08/08/2012 ~ CoDeRs
                Lua.Events.AttachEvent("RAID_TARGET_UPDATE", LuaEvents.PARTY_INVITE_CANCEL);

                //Game Master Response Received
                Lua.Events.AttachEvent("GMRESPONSE_RECEIVED", LuaEvents.GMRESPONSE_RECEIVED);	//Unit Received Whisper/Event from Game Master

                //Screen Shot Events Here
                Lua.Events.AttachEvent("SCREENSHOT_SUCCEEDED", LuaEvents.SCREENSHOT_SUCCEEDED);	//Screen Capture Sucsessfull
                Lua.Events.AttachEvent("SCREENSHOT_FAILED", LuaEvents.SCREENSHOT_FAILED);		//Screen Capture Failed

                //Player Token Events Here
                Lua.Events.AttachEvent("HONOR_CURRENCY_UPDATE", LuaEvents.HONOR_CURRENCY_UPDATE);//Unit Receives Honor Points
                Lua.Events.AttachEvent("LFG_COMPLETION_REWARD", LuaEvents.LFG_COMPLETION_REWARD);//Unit Completes Dungeon, Gains Reward from Random Queue - Parse Data for JP/VP

                //Player Talent Tree Change Events Here
                Lua.Events.AttachEvent("ACTIVE_TALENT_GROUP_CHANGED", LuaEvents.ACTIVE_TALENT_GROUP_CHANGED); //Unit Changes Spec

                //Death Events Here
                Lua.Events.AttachEvent("PLAYER_DEAD", LuaEvents.PLAYER_DEAD);					//Unit Died
                Lua.Events.AttachEvent("PLAYER_UNGHOST", LuaEvents.PLAYER_UNGHOST);				//Unit Alive (Retrive Body, Player Res, Spirit Res)

                //B.net 
                Lua.Events.AttachEvent("CHAT_MSG_BN_WHISPER", ChatFunctions.WoWChat_BattleNet_Whisper); //Unit Received Battle.Net Whisper

                // Setting Current Time as Last Update
                last_update = DateTime.Now;

                // Checking Database Version for Updates
                Logging.Write(LogLevel.Normal, Colors.Green, "[WatchMyToon] - Check DBVersion");
                sCommandCheck = SQLConnector.SendJSON("[{\"Limit\":\"0\"}]", "{\"Query\":\"UpdateDatabase\"}", "{\"Limit\":\"0\"}");//SQLUpdate.VersionControl();
                Logging.Write(LogLevel.Verbose, Colors.Orange, "[WatchMyToon] - Database Update Report: " + sCommandCheck);

                //Starting Initialization on Character Details / Database Inserts
                Logging.Write(LogLevel.Normal, Colors.Green, "[WatchMyToon] - Register Character");
                try
                {
                    //Pulling Current Characters ID
                    Logging.Write(LogLevel.Normal, Colors.Green, "[WatchMyToon] - Getting ID");
                    nToonDetails = SQLConnector.SendJSON("[{\"TAB\":\"TABToons\"},{\"szName\":\"" + StyxWoW.Me.Name + "\"}]", "{\"Query\":\"Select\"}", "{\"Limit\":\"0\"}");
                    JObject CurrentToon = JObject.Parse(nToonDetails.Substring(1, (nToonDetails.Length - 2)));
                    

                    if (Convert.ToInt32(CurrentToon.Count.ToString()) > 1)
                    {
                        Int32.TryParse(CurrentToon["nToonId"].ToString(), out nToonId);
                        Logging.Write(LogLevel.Verbose, Colors.Orange, "[WatchMyToon] - ID Retreived: " + CurrentToon["nToonId"].ToString());

                        //Might as well do a full update... Might filter out bugs and cut down on pulse times... 
                        Logging.Write(LogLevel.Normal, Colors.Green, "[WatchMyToon] - Updating Character Details");
                        sCommandCheck = SQLConnector.SendJSON("[{\"TAB\":\"TABToonsDetail\"},{\"nToonId\":\"" + nToonId + "\"},{\"nCurrentLvl\":\"" + StyxWoW.Me.Level + "\"},{\"nCurrentXp\":\"" + StyxWoW.Me.Experience + "\"},{\"nNextLvlXp\":\"" + StyxWoW.Me.NextLevelExperience + "\"},{\"szPowerType\":\"" + StyxWoW.Me.PowerType.ToString() + "\"},{\"szPower\":\"" + StyxWoW.Me.PowerPercent.ToString() + "\"},{\"szHealth\":\"" + StyxWoW.Me.HealthPercent.ToString() + "\"},{\"szMoneyInCopper\":\"" + StyxWoW.Me.Copper.ToString() + "\"},{\"bIsInGuild\":\"" + UnitFunctions.isInGuild() + "\"},{\"bIsInParty\":\"" + StyxWoW.Me.IsInParty.ToString() + "\"},{\"nFreeBagSlot\":\"" + StyxWoW.Me.FreeBagSlots + "\"},{\"nTotalBagSlot\":\"" + UnitFunctions.getTotalBagCount() + "\"}]", "{\"Query\":\"Update\"}", "{\"Limit\":\"0\"}");
                        Logging.Write(LogLevel.Verbose, Colors.Orange, "[WatchMyToon] - Toon Details Updated Report: " + sCommandCheck);
                    }
                    else
                    {
                        //Create New Row for Current Character	
                        //Setting Faction Class Realm for Character Creation and Single Update
                        List<string> Class = Lua.GetReturnValues("return UnitClass(\"player\")");
                        List<string> GenderValue = Lua.GetReturnValues("return UnitSex(\"player\")");
                        List<string> Realm = Lua.GetReturnValues("return GetRealmName()");
                        
                        if (StyxWoW.Me.IsAlliance)
                            Side = "Alliance";
                        else
                            Side = "Horde";

                        Logging.Write(LogLevel.Normal, Colors.Green, "[WatchMyToon] - Create new Record");
                        sCommandCheck = SQLConnector.SendJSON("[{\"TAB\":\"TABToons\"},{\"nToonId\":\"\"},{\"szRealm\":\"" +  Realm[0] + "\"},{\"szFaction\":\"" + Side + "\"},{\"szGender\":\"" + Gender[(Convert.ToInt32(GenderValue[0])-1)] + "\"},{\"szRace\":\"" + StyxWoW.Me.Race + "\"},{\"szClass\":\"" + Class[0] + "\"},{\"szCurrentSpec\":\"" + UnitFunctions.getSpec() + "\"},{\"szName\":\"" + StyxWoW.Me.Name + "\"},{\"szPlatform\":\"WOW\"}]", "{\"Query\":\"Insert\"}", "{\"Limit\":\"0\"}");
                        Logging.Write(LogLevel.Verbose, Colors.Orange, "[WatchMyToon] - ID Created Report: " + sCommandCheck);

                        Logging.Write(LogLevel.Normal, Colors.Green, "[WatchMyToon] - Getting ID");
                        nToonDetails = SQLConnector.SendJSON("[{\"TAB\":\"TABToons\"},{\"szName\":\"" + StyxWoW.Me.Name + "\"}]", "{\"Query\":\"Select\"}", "{\"Limit\":\"0\"}");
                        JObject NewCurrentToon = JObject.Parse(nToonDetails.Substring(1, (nToonDetails.Length - 2)));

                        Logging.Write(LogLevel.Verbose, Colors.Orange, "[WatchMyToon] - ID Retreived: " + NewCurrentToon["nToonId"].ToString());

                        if (Convert.ToInt32(NewCurrentToon.Count.ToString()) > 1)
                        {
                            Int32.TryParse(NewCurrentToon["nToonId"].ToString(), out nToonId);
                            Logging.Write(LogLevel.Normal, Colors.Green, "[WatchMyToon] - Inserting Character Details");
                            sCommandCheck = SQLConnector.SendJSON("[{\"TAB\":\"TABToonsDetail\"},{\"nToonId\":\"" + nToonId + "\"},{\"nCurrentLvl\":\"" + StyxWoW.Me.Level + "\"},{\"nCurrentXp\":\"" + StyxWoW.Me.Experience + "\"},{\"nNextLvlXp\":\"" + StyxWoW.Me.NextLevelExperience + "\"},{\"szPowerType\":\"" + StyxWoW.Me.PowerType.ToString() + "\"},{\"szPower\":\"" + StyxWoW.Me.PowerPercent.ToString() + "\"},{\"szHealth\":\"" + StyxWoW.Me.HealthPercent.ToString() + "\"},{\"szMoneyInCopper\":\"" + StyxWoW.Me.Copper.ToString() + "\"},{\"bIsInGuild\":\"" + UnitFunctions.isInGuild() + "\"},{\"bIsInParty\":\"" + StyxWoW.Me.IsInParty.ToString() + "\"},{\"nFreeBagSlot\":\"" + StyxWoW.Me.FreeBagSlots + "\"},{\"nTotalBagSlot\":\"" + UnitFunctions.getTotalBagCount() + "\"}]", "{\"Query\":\"Insert\"}", "{\"Limit\":\"0\"}");
                            Logging.Write(LogLevel.Verbose, Colors.Orange, "[WatchMyToon] - Details Created Report: " + sCommandCheck);

                            Logging.Write(LogLevel.Normal, Colors.Green, "[WatchMyToon] - Inserting Blank Guild Information For Update");
                            sCommandCheck = SQLConnector.SendJSON("[{\"TAB\":\"TABGuildInformation\"},{\"UID\":\"\"},{\"nToonId\":\"" + nToonId + "\"}]", "{\"Query\":\"Insert\"}", "{\"Limit\":\"0\"}");
                            Logging.Write(LogLevel.Verbose, Colors.Orange, "[WatchMyToon] - Guild Created Report: " + sCommandCheck);
                        }
                        else
                        {
                            Logging.Write(LogLevel.Normal, Colors.Red, "[WatchMyToon] - Inserting Character Details Failed");
                        }
                    }
                }
                catch (Exception ex)
                {
                    Logging.Write(LogLevel.Normal, Colors.Red, "[WatchMyToon] - Character Initializtion!");
                    Logging.Write(LogLevel.Diagnostic, Colors.Red, "[WatchMyToon] - " + ex);
                }


                //Clearing Database to Elimiate Bugs
                Logging.Write(LogLevel.Normal, Colors.Green, "[WatchMyToon] - Clear database");
                Clear();                

                //Loading Characters Guild Details into the Database
                Logging.Write(LogLevel.Normal, Colors.Green, "[WatchMyToon] - Load Guild Information");
                UnitFunctions.updateGuildInfo();

                //Loading Characters Token/Currency Details into the Database
                Logging.Write(LogLevel.Normal, Colors.Green, "[WatchMyToon] - Load Currency Tokens");
                UnitFunctions.updateTokens();

                //Loading Characters Reputation Details into the Database
                Logging.Write(LogLevel.Normal, Colors.Green, "[WatchMyToon] - Load Available Reputations");
                UnitFunctions.updateReputations();

                //Inserting Dummy Screenshot Row
                Logging.Write(LogLevel.Normal, Colors.Green, "[WatchMyToon] - Load Dummy ScreenShot Information");
                sCommandCheck = SQLConnector.SendJSON("[{\"TAB\":\"TABScreenShots\"},{\"picScreenShot\":\"\"},{\"nToonId\":\"" + nToonId + "\"}]", "{\"Query\":\"Insert\"}", "{\"Limit\":\"0\"}");
                Logging.Write(LogLevel.Verbose, Colors.Orange, "[WatchMyToon] - Insert Dummy Screenshot Row: " + sCommandCheck);

                //WOOT No Errors Lets get crackalacking
                Logging.Write(LogLevel.Normal, Colors.Green, "[WatchMyToon] - Successfully loaded");
                IsInitialized = true;
                stop = false;
            }
            catch (Exception ex)
            {
                Logging.Write(LogLevel.Normal, Colors.Red, "[WatchMyToon] - Unable to Connect! Please check the UserDSN!");
                Logging.Write(LogLevel.Diagnostic, Colors.Red, "[WatchMyToon] - " + ex.Message);
            }
        }
        
        // HonorBuddy Pulse Event
        public override void Pulse()
        {
            if (doWork)
            {
                try
                {
                    if (workerThread == null)
                    {
                        workerThread = new Thread(DoWork);
                    }

                    if (!workerThread.IsAlive)
                    {
                        workerThread.Start();
                        Logging.Write(LogLevel.Normal, Colors.Orange, "[WatchMyToon] - Updatethread started");
                    }
                }
                catch (Exception ex)
                {
                    Logging.Write(LogLevel.Normal, Colors.Red, "[WatchMyToon] - Generic Pulse Error!");
                    Logging.Write(LogLevel.Diagnostic, Colors.Red, "[WatchMyToon] - " + ex.Message);
                }
            }
        }

        public void EventHandler(string whichEvent, string eventText)
        {
            switch (whichEvent)
            {
                case "ACCEPT_GROUP":
                    Lua.DoString("AcceptGroup();");
                    Logging.Write(LogLevel.Normal, Colors.Purple, "[WatchMyToon] - Group Invite Accepted");
                    break;
                case "LEAVE_GROUP":
                    Lua.DoString("LeaveParty();");
                    Logging.Write(LogLevel.Normal, Colors.Purple, "[WatchMyToon] - Group Left");
                    break;
                case "DECLINE_GROUP":
                    Lua.DoString("DeclineGroup();");
                    Logging.Write(LogLevel.Normal, Colors.Purple, "[WatchMyToon] - Group Invite Declined");
                    break;
                case "INVITE_GROUP":
                    Lua.DoString("InviteUnit(\"" + eventText + "\");");
                    Logging.Write(LogLevel.Normal, Colors.Purple, "[WatchMyToon] - Group Invite Sent");
                    break;
               
                
                case "ACCEPT_GUILD":
                    Lua.DoString("AcceptGuild();");
                    Logging.Write(LogLevel.Normal, Colors.Purple, "[WatchMyToon] - Guild Invite Accepted");
                    break;
                case "LEAVE_GUILD":
                    Lua.DoString("GuildLeave();");
                    Logging.Write(LogLevel.Normal, Colors.Purple, "[WatchMyToon] - Guild Left");
                    break;
                case "DECLINE_GUILD":
                    Lua.DoString("DeclineGuild();");
                    Logging.Write(LogLevel.Normal, Colors.Purple, "[WatchMyToon] - Guild Invite Declined");
                    break;
                case "INVITE_GUILD":
                    Lua.DoString("GuildInvite(\"" + eventText + "\");");
                    Logging.Write(LogLevel.Normal, Colors.Purple, "[WatchMyToon] - Guild Invite Sent");
                    break;
                
                
                case "SEND_EMOTE":
                    Lua.DoString("DoEmote(\"" + eventText + "\");");
                    Logging.Write(LogLevel.Normal, Colors.Purple, "[WatchMyToon] - Emote Sent");
                    break;
                case "FORCE_QUIT":
                    Lua.DoString("ForceQuit();");
                    Logging.Write(LogLevel.Normal, Colors.Purple, "[WatchMyToon] - Game Killed");
                    break;
                case "IGNORE_PLAYER":
                    Lua.DoString("AddIgnore(\"" + eventText + "\");");
                    Logging.Write(LogLevel.Normal, Colors.Purple, "[WatchMyToon] - Player Ignored");
                    break;
                case "TAKE_SCREENSHOT":
                    string filename = Application.StartupPath + "\\Plugins\\WatchMyToon\\ScreenShots\\" + StyxWoW.Me.Name + "_" + nToonId + ".png";
                    //scr.CaptureWindowToFile(ObjectManager, filename, System.Drawing.Imaging.ImageFormat.Png);
                    break;
                default:
                    break;
            }
        }

        // The Threadfunction
        public void DoWork()
        {
            while (!stop)
            {
                try
                {
                    //Check for 30 Second Update ... Would like to remove this.. 
                    if (last_update <= DateTime.Now.AddSeconds(-30))
                    {
                        try
                        {
                            //Setting Debug Messages "updateSection"
                            updateSection = "Entered Do Work Section";

                            //Updating Update Tick
                            updateSection = "Updating Update Tick";
                            last_update = DateTime.Now;
                            sCommandCheck = SQLConnector.SendJSON("[{\"TAB\":\"TABToons\"},{\"nToonId\":\"" + nToonId + "\"},{\"dtLastUpdate\":\"CURRENT_TIMESTAMP\"}]", "{\"Query\":\"UpdateTS\"}", "{\"Limit\":\"0\"}");
                            Logging.Write(LogLevel.Verbose, Colors.Orange, "[WatchMyToon] - Toon Update Pulse Report: " + sCommandCheck);

                            //Updating Guild Information
                            //updateSection = "Getting Guild Information";
                            //UnitFunctions.updateGuildInfo();

                            //Check if we are in a loading screen or menu
                            if (!bIsInLoadingScreen)
                            {
                                //Update Current Position
                                updateSection = "Getting Position Information";
                                UnitFunctions.updateCurrentPosition();
                            }
                        }
                        catch (Exception ex)
                        {
                            Logging.Write(LogLevel.Normal, Colors.Red, "[WatchMyToon] - Error while `Timed` Pulse Update: " + updateSection + "!");
                            Logging.Write(LogLevel.Diagnostic, Colors.Red, "[WatchMyToon] - " + ex.Message);
                        }
                    }
                    try //Genereal Pulse Update (Triggers during Timmed and Untimmed Updates)
                    {                                
                        // Handle Message Stuff
                        updateSection = "Query for Messages";
                        string nMessageDetails = SQLConnector.SendJSON("[{\"TAB\":\"TABMessageToSend\"},{\"nToonId\":\"" + nToonId  + "\"}]", "{\"Query\":\"Select\"}", "{\"Limit\":\"0\"}");
                        JArray MessageEventList = JArray.Parse(nMessageDetails);

                        updateSection = "Parse Messages Query";
                        foreach (JObject CurrentEvent in MessageEventList)
                        {
                            if (CurrentEvent["Limit"] == null)
                            {
                                int nMsgId = Convert.ToInt32(CurrentEvent["nMsgId"].ToString());
                                string MESSAGE_TYPE = CurrentEvent["szMessageType"].ToString();

                                if (MESSAGE_TYPE.Equals("SAY_MESSAGE"))
                                {
                                    if (StyxWoW.Me.IsAlive)
                                    {
                                        updateSection = "Sending Say Message Type";
                                        ChatFunctions.SendToWoWChat(MESSAGE_TYPE, CurrentEvent["szMessageText"].ToString(), CurrentEvent["szMessagePartner"].ToString());
                                        sCommandCheck = SQLConnector.SendJSON("[{\"TAB\":\"TABMessageToSend\"},{\"nMsgId\":\"" + nMsgId + "\"}]", "{\"Query\":\"Clear\"}", "{\"Limit\":\"0\"}");
                                        Logging.Write(LogLevel.Verbose, Colors.Orange, "[WatchMyToon] - Delete Say Chat Message Report: " + sCommandCheck);
                                    }

                                }
                                else if (MESSAGE_TYPE.Equals("YELL_MESSAGE"))
                                {
                                    if (StyxWoW.Me.IsAlive)
                                    {
                                        updateSection = "Sending Yell Message Type";
                                        ChatFunctions.SendToWoWChat(MESSAGE_TYPE, CurrentEvent["szMessageText"].ToString(), CurrentEvent["szMessagePartner"].ToString());
                                        sCommandCheck = SQLConnector.SendJSON("[{\"TAB\":\"TABMessageToSend\"},{\"nMsgId\":\"" + nMsgId + "\"}]", "{\"Query\":\"Clear\"}", "{\"Limit\":\"0\"}");
                                        Logging.Write(LogLevel.Verbose, Colors.Orange, "[WatchMyToon] - Delete Yell Chat Message Report: " + sCommandCheck);
                                    }
                                }
                                else
                                {
                                    updateSection = "Sending All Other Message Types";
                                    ChatFunctions.SendToWoWChat(MESSAGE_TYPE, CurrentEvent["szMessageText"].ToString(), CurrentEvent["szMessagePartner"].ToString());
                                    sCommandCheck = SQLConnector.SendJSON("[{\"TAB\":\"TABMessageToSend\"},{\"nMsgId\":\"" + nMsgId + "\"}]", "{\"Query\":\"Clear\"}", "{\"Limit\":\"0\"}");
                                    Logging.Write(LogLevel.Verbose, Colors.Orange, "[WatchMyToon] - Delete All Other Chat Message Report: " + sCommandCheck);
                                }
                            }
                        }

                        // Handle Group Stuff
                        updateSection = "Query for Group Invites / Accept / Deny";
                        string nGroupInvitesDetails = SQLConnector.SendJSON("[{\"TAB\":\"TABGroupInvites\"},{\"nToonId\":\"" + nToonId  + "\"}]", "{\"Query\":\"Select\"}", "{\"Limit\":\"0\"}");
                        JArray GroupEventList = JArray.Parse(nGroupInvitesDetails);

                        updateSection = "Parse Group Query";
                        foreach (JObject CurrentEvent in GroupEventList)
                        {
                            if (CurrentEvent["Limit"].ToString() != "0")
                            {
                                string GROUP_HANDLE = CurrentEvent["szStatus"].ToString();
                                string GROUP_INVITEE = CurrentEvent["szInviterName"].ToString();
                                switch (GROUP_HANDLE)
                                {
                                    case "REQUEST_GROUP":
                                        updateSection = "Request Group Invite";
                                        break;
                                    case "DECLINE_GROUP":
                                        updateSection = "Decline Group Invite";
                                        EventHandler(GROUP_HANDLE, null);
                                        sCommandCheck = SQLConnector.SendJSON("[{\"TAB\":\"TABGroupInvites\"},{\"nToonId\":\"" + nToonId + "\"}]", "{\"Query\":\"Clear\"}", "{\"Limit\":\"0\"}");
                                        Logging.Write(LogLevel.Verbose, Colors.Orange, "[WatchMyToon] - Delete Group Decline Report: " + sCommandCheck);
                                        break;
                                    case "ACCEPT_GROUP":
                                        updateSection = "Accept Group Invite";
                                        EventHandler(GROUP_HANDLE, null);
                                        sCommandCheck = SQLConnector.SendJSON("[{\"TAB\":\"TABGroupInvites\"},{\"nToonId\":\"" + nToonId + "\"}]", "{\"Query\":\"Clear\"}", "{\"Limit\":\"0\"}");
                                        Logging.Write(LogLevel.Verbose, Colors.Orange, "[WatchMyToon] - Delete Group Accept Report: " + sCommandCheck);
                                        break;
                                    case "LEAVE_GROUP":
                                        updateSection = "Leave Group Invite";
                                        EventHandler(GROUP_HANDLE, null);
                                        sCommandCheck = SQLConnector.SendJSON("[{\"TAB\":\"TABToonsDetail\"},{\"nToonId\":\"" + nToonId + "\"},{\"bIsInParty\":\"0\"}]", "{\"Query\":\"Update\"}", "{\"Limit\":\"0\"}");
                                        Logging.Write(LogLevel.Verbose, Colors.Orange, "[WatchMyToon] - Delete Group Leave Report: " + sCommandCheck);
                                        break;
                                    case "INVITE_GROUP":
                                        updateSection = "Send Group Invite";
                                        EventHandler(GROUP_HANDLE, GROUP_INVITEE);
                                        sCommandCheck = SQLConnector.SendJSON("[{\"TAB\":\"TABGroupInvites\"},{\"nToonId\":\"" + nToonId + "\"}]", "{\"Query\":\"Clear\"}", "{\"Limit\":\"0\"}");
                                        Logging.Write(LogLevel.Verbose, Colors.Orange, "[WatchMyToon] - Delete Group Invite Report: " + sCommandCheck);
                                        break;

                                    default:
                                        updateSection = "Default Group Invite";
                                        EventHandler(GROUP_HANDLE, null);
                                        break;
                                }
                            }
                        }

                        // Handle Guild Stuff
                        updateSection = "Query for Guild Invites / Accept / Deny";
                        string nGuildInvitesDetails = SQLConnector.SendJSON("[{\"TAB\":\"TABGroupInvites\"},{\"nToonId\":\"" + nToonId + "\"}]", "{\"Query\":\"Select\"}", "{\"Limit\":\"0\"}");
                        JArray GuildEventList = JArray.Parse(nGuildInvitesDetails);

                        updateSection = "Parse Guild Query";
                        foreach (JObject CurrentEvent in GuildEventList)
                        {
                            if (CurrentEvent["Limit"].ToString() != "0")
                            {
                                string GUILD_HANDLE = CurrentEvent["szStatus"].ToString();
                                string GUILD_INVITEE = CurrentEvent["szInviterName"].ToString();
                                switch (GUILD_HANDLE)
                                {
                                    case "REQUEST_GUILD":
                                        updateSection = "Request Guild Invite";
                                        break;
                                    case "DECLINE_GUILD":
                                        updateSection = "Decline Guild Invite";
                                        EventHandler(GUILD_HANDLE, null);
                                        sCommandCheck = SQLConnector.SendJSON("[{\"TAB\":\"TABGuildInvites\"},{\"nToonId\":\"" + nToonId + "\"}]", "{\"Query\":\"Clear\"}", "{\"Limit\":\"0\"}");
                                        Logging.Write(LogLevel.Verbose, Colors.Orange, "[WatchMyToon] - Delete Guild Decline Report: " + sCommandCheck);
                                        break;
                                    case "ACCEPT_GUILD":
                                        updateSection = "Accept Guild Invite";
                                        EventHandler(GUILD_HANDLE, null);
                                        sCommandCheck = SQLConnector.SendJSON("[{\"TAB\":\"TABGuildInvites\"},{\"nToonId\":\"" + nToonId + "\"}]", "{\"Query\":\"Clear\"}", "{\"Limit\":\"0\"}");
                                        Logging.Write(LogLevel.Verbose, Colors.Orange, "[WatchMyToon] - Delete Guild Accept Report: " + sCommandCheck);
                                        break;
                                    case "LEAVE_GUILD":
                                        updateSection = "Leave Group Invite";
                                        EventHandler(GUILD_HANDLE, null);
                                        sCommandCheck = SQLConnector.SendJSON("[{\"TAB\":\"TABToonsDetail\"},{\"nToonId\":\"" + nToonId + "\"},{\"bIsInGuild\":\"0\"}]", "{\"Query\":\"Update\"}", "{\"Limit\":\"0\"}");
                                        Logging.Write(LogLevel.Verbose, Colors.Orange, "[WatchMyToon] - Delete Guild Leave Report: " + sCommandCheck);
                                        break;
                                    case "INVITE_GUILD":
                                        updateSection = "Accept Guild Invite";
                                        EventHandler(GUILD_HANDLE, GUILD_INVITEE);
                                        sCommandCheck = SQLConnector.SendJSON("[{\"TAB\":\"TABGuildInvites\"},{\"nToonId\":\"" + nToonId + "\"}]", "{\"Query\":\"Clear\"}", "{\"Limit\":\"0\"}");
                                        Logging.Write(LogLevel.Verbose, Colors.Orange, "[WatchMyToon] - Delete Guild Invite Report: " + sCommandCheck);
                                        break;
                                    default:
                                        updateSection = "Default Guild Invite";
                                        EventHandler(GUILD_HANDLE, null);
                                        break;
                                }
                            }
                        }
                        // Handle Event Stuff
                        updateSection = "Query for Events";
                        string nCurrentEventDetails = SQLConnector.SendJSON("[{\"TAB\":\"TABEventHandling\"},{\"nToonId\":\"" + nToonId  + "\"}]", "{\"Query\":\"Select\"}", "{\"Limit\":\"0\"}");
                        JArray EventList = JArray.Parse(nCurrentEventDetails);

                        updateSection = "Parse Event Query";
                        foreach (JObject CurrentEvent in EventList)
                        {
                            if (CurrentEvent["Limit"].ToString() != "0")
                            {
                                int EVENT_ID = Convert.ToInt32(CurrentEvent["nEventId"]);
                                string EVENT_HANDLE = CurrentEvent["szEventDesc"].ToString();
                                string EVENT_TEXT = CurrentEvent["szEventText"].ToString();

                                if (EVENT_HANDLE.Equals("SEND_EMOTE"))
                                {
                                    if (StyxWoW.Me.IsAlive)
                                    {
                                        EventHandler(EVENT_HANDLE, EVENT_TEXT);
                                        sCommandCheck = SQLConnector.SendJSON("[{\"TAB\":\"TABEventHandling\"},{\"nEventId\":\"" + EVENT_ID + "\"}]", "{\"Query\":\"Clear\"}", "{\"Limit\":\"0\"}");
                                        Logging.Write(LogLevel.Verbose, Colors.Orange, "[WatchMyToon] - Delete Send Emote Event Report: " + sCommandCheck);
                                    }
                                }
                                else if (EVENT_HANDLE.Equals("FORCE_QUIT"))
                                {
                                    EventHandler(EVENT_HANDLE, EVENT_TEXT);
                                    sCommandCheck = SQLConnector.SendJSON("[{\"TAB\":\"TABEventHandling\"},{\"nEventId\":\"" + EVENT_ID + "\"}]", "{\"Query\":\"Clear\"}", "{\"Limit\":\"0\"}");
                                    Logging.Write(LogLevel.Verbose, Colors.Orange, "[WatchMyToon] - Delete Force Quit Event Report: " + sCommandCheck);
                                }
                                else
                                {
                                    EventHandler(EVENT_HANDLE, EVENT_TEXT);
                                    sCommandCheck = SQLConnector.SendJSON("[{\"TAB\":\"TABEventHandling\"},{\"nEventId\":\"" + EVENT_ID + "\"}]", "{\"Query\":\"Clear\"}", "{\"Limit\":\"0\"}");
                                    Logging.Write(LogLevel.Verbose, Colors.Orange, "[WatchMyToon] - Delete Other General Event Report: " + sCommandCheck);
                                }
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        Logging.Write(LogLevel.Normal, Colors.Red, "[WatchMyToon] - Error while Pulse Update - " + updateSection + "!");
                        Logging.Write(LogLevel.Diagnostic, Colors.Red, "[WatchMyToon] - " + ex.Message);
                    }
                       
                }
                catch (Exception ex)
                {
                    Logging.Write(LogLevel.Normal, Colors.Red, "[WatchMyToon] - Error while generic DoWork - " + updateSection + "!");
                    Logging.Write(LogLevel.Diagnostic, Colors.Red, "[WatchMyToon] - " + ex.Message);
                }
            }
        }
        // Clear all first
        public void Clear()
        {
            try
            {
                string[] Check = new string[9];
                string[] Table = new string[9];

                Table[0] = "TabMessageToSend";
                Check[0] = SQLConnector.SendJSON("[{\"TAB\":\"TABMessageToSend\"},{\"nToonId\":\"" + nToonId + "\"}]", "{\"Query\":\"Clear\"}", "{\"Limit\":\"0\"}");

                Table[1] = "TABMessageReceive";
                Check[1] = SQLConnector.SendJSON("[{\"TAB\":\"TABMessageReceive\"},{\"nToonId\":\"" + nToonId + "\"}]", "{\"Query\":\"Clear\"}", "{\"Limit\":\"0\"}");

                Table[2] = "TABEventHandling";
                Check[2] = SQLConnector.SendJSON("[{\"TAB\":\"TABEventHandling\"},{\"nToonId\":\"" + nToonId + "\"}]", "{\"Query\":\"Clear\"}", "{\"Limit\":\"0\"}");

                Table[3] = "TABGuildInvites";
                Check[3] = SQLConnector.SendJSON("[{\"TAB\":\"TABGuildInvites\"},{\"nToonId\":\"" + nToonId + "\"}]", "{\"Query\":\"Clear\"}", "{\"Limit\":\"0\"}");

                Table[4] = "TABGroupInvites";
                Check[4] = SQLConnector.SendJSON("[{\"TAB\":\"TABGroupInvites\"},{\"nToonId\":\"" + nToonId + "\"}]", "{\"Query\":\"Clear\"}", "{\"Limit\":\"0\"}");

                Table[5] = "TABLoots";
                Check[5] = SQLConnector.SendJSON("[{\"TAB\":\"TABLoots\"},{\"nToonId\":\"" + nToonId + "\"}]", "{\"Query\":\"Clear\"}", "{\"Limit\":\"0\"}");

                Table[6] = "TABReputation";
                Check[6] = SQLConnector.SendJSON("[{\"TAB\":\"TABReputation\"},{\"iToonID\":\"" + nToonId + "\"}]", "{\"Query\":\"Clear\"}", "{\"Limit\":\"0\"}");

                Table[7] = "TABScreenShots";
                Check[7] = SQLConnector.SendJSON("[{\"TAB\":\"TABScreenShots\"},{\"nToonId\":\"" + nToonId + "\"}]", "{\"Query\":\"Clear\"}", "{\"Limit\":\"0\"}");

                Table[8] = "TABToonsTokens";
                Check[8] = SQLConnector.SendJSON("[{\"TAB\":\"TABToonsTokens\"},{\"nToonId\":\"" + nToonId + "\"}]", "{\"Query\":\"Clear\"}", "{\"Limit\":\"0\"}");

                var aCurrentStatus = Table.Zip(Check, (t,c) => new {Tables = t, Checks = c});

                foreach (var sCurrentClear in aCurrentStatus)
                {
                    if (sCurrentClear.Checks != "SQL Query Successfull!")
                    {
                        Logging.Write(LogLevel.Verbose, Colors.Orange, sCurrentClear.Tables + " - Failed - " + sCurrentClear.Checks);
                    }
                }
            }
            catch (Exception ex)
            {
                Logging.Write(LogLevel.Normal, Colors.Red, "[WatchMyToon] - Error Clearing Database!");
                Logging.Write(LogLevel.Diagnostic, Colors.Red, "[WatchMyToon] - " + ex.Message);
            }
        }

        // Unload the Do Work Thread from Pulse
        public override void Dispose()
        {
            IsInitialized = false;
            stop = true;
            while (workerThread.IsAlive)
            {
                Logging.Write(LogLevel.Normal, Colors.Red, "[WatchMyToon] - Attempting to Kill Thread!");
                try
                {
                    workerThread.Abort();
                }
                catch (Exception ex)
                {
                    Logging.Write(LogLevel.Normal, Colors.Red, "[WatchMyToon] - Killing Thread Failed!");
                    Logging.Write(LogLevel.Diagnostic, Colors.Red, "[WatchMyToon] - " + ex.Message);
                }
            }

            Logging.Write(LogLevel.Normal, Colors.Green, "[WatchMyToon] - Updatethread killed");
        }
    }
}

